package com.biscuit.page.basicservice.websocket.chat_room;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;

import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author biscuit
 * @createTime 2024/6/22 15:09
 */
public class ChatRoomWebSocketHandler {

    // roomId: (userUid : context)
    private final static Map<Long, Map<String, ChatRoomWebSocketContext>> WEB_SOCKET_MAP = new ConcurrentHashMap<>();

    // sessionId : roomId,userUid
    private final static Map<String, String> SESSION_MAP = new ConcurrentHashMap<>();

    // 向指定聊天室的在线用户上下文对象集合新增
    public static void putByChatRoom(Long chatRoomId, ChatRoomWebSocketContext context) {
        // 获取指定聊天室下的所有在线用户上下文对象
        Map<String, ChatRoomWebSocketContext> contextMap = WEB_SOCKET_MAP.get(chatRoomId);

        // 如果当前聊天室未初始化，则通过双重校验进行加锁初始化
        if (CollectionUtils.isEmpty(contextMap)) {
            contextMap = WEB_SOCKET_MAP.get(chatRoomId);
            synchronized (WEB_SOCKET_MAP) {
                if (CollectionUtils.isEmpty(contextMap)) {
                    contextMap = new ConcurrentHashMap<>();
                    WEB_SOCKET_MAP.put(chatRoomId, contextMap);
                }
            }
        }

        // 向指定聊天室下的在线用户上下文对象集合中插入一条
        contextMap.put(context.getUserUid(), context);

        // 记录本次 websocket 会话对象与上下文对象的映射关系
        SESSION_MAP.put(context.getSession().getId(),
                chatRoomId.toString() + "," + context.getUserUid());
    }

    /**
     * 获取指定聊天室中指定用户的上下文对象
     */
    public static ChatRoomWebSocketContext getContext(Long chatRoomId, String userUid) {
        // 获取指定聊天室下的素有在线用户上下文对象
        Map<String, ChatRoomWebSocketContext> contextMap = Optional.ofNullable(WEB_SOCKET_MAP.get(chatRoomId))
                .orElse(new ConcurrentHashMap<>());

        // 获取指定用户的在线用户上下文对象
        return contextMap.get(userUid);
    }

    /**
     * 获取指定聊天室下的所有在线用户上下文对象集合
     */
    public static Map<String, ChatRoomWebSocketContext> getContextMap(Long chatRoomId) {
        return WEB_SOCKET_MAP.get(chatRoomId);
    }

    /**
     * 删除指定聊天室中指定在线用户的上下文对象
     */
    public static void delContext(Long chatRoomId, String userUid) {
        // 获取指定聊天室下的素有在线用户上下文对象
        Map<String, ChatRoomWebSocketContext> contextMap = WEB_SOCKET_MAP.get(chatRoomId);

        // 判断指定聊天室下的所有用户在线上下文对象集合是否存在
        if (CollectionUtils.isNotEmpty(contextMap)) {
            String sessionId = contextMap.get(userUid).getSession().getId();
            contextMap.remove(userUid);
            SESSION_MAP.remove(sessionId);
        }
    }

    /**
     * 根据 sessionId 删除该会话的上下文对象
     */
    public static void delContext(String sessionId) {
        String info = SESSION_MAP.get(sessionId);
        if (StringUtils.isNotBlank(info)) {
            String[] infos = info.split(",");
            delContext(Long.parseLong(infos[0]), infos[1]);
        }
    }

    public static String[] getSessionMapping(String sessionId) {
        String info = SESSION_MAP.get(sessionId);
        return StringUtils.isNotBlank(info) ? info.split(",") : null;
    }

}
